/*
* Created by boil on 2023/2/22.
*/

#ifndef RENDU_CORE_META_ADL_POINTER_H_
#define RENDU_CORE_META_ADL_POINTER_H_

namespace rendu {

/**
 * @brief ADL based lookup function for dereferencing meta pointer-like types.
 * @tparam Type Element type.
 * @param value A pointer-like object.
 * @return The value returned from the dereferenced pointer.
 */
template<typename Type>
decltype(auto) dereference_meta_pointer_like(const Type &value) {
  return *value;
}

/**
 * @brief Fake ADL based lookup function for meta pointer-like types.
 * @tparam Type Element type.
 */
template<typename Type>
struct adl_meta_pointer_like {
  /**
   * @brief Uses the default ADL based lookup method to resolve the call.
   * @param value A pointer-like object.
   * @return The value returned from the dereferenced pointer.
   */
  static decltype(auto) dereference(const Type &value) {
    return dereference_meta_pointer_like(value);
  }
};

} // namespace rendu

#endif //RENDU_CORE_META_ADL_POINTER_H_
